package com.tencent.hummingbird.portal.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tencent.hummingbird.portal.exception.ServiceException;
import com.tencent.hummingbird.portal.mapper.ClassroomMapper;
import com.tencent.hummingbird.portal.mapper.UserCollectMapper;
import com.tencent.hummingbird.portal.mapper.UserRoleMapper;
import com.tencent.hummingbird.portal.pojo.*;
import com.tencent.hummingbird.portal.mapper.UserMapper;
import com.tencent.hummingbird.portal.service.IQuestionService;
import com.tencent.hummingbird.portal.service.IUserCollectService;
import com.tencent.hummingbird.portal.service.IUserQuestionService;
import com.tencent.hummingbird.portal.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tencent.hummingbird.portal.vo.*;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author yxb
 * @since 2024-01-10
 */
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private ClassroomMapper classroomMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;
    @Transactional //放入同一事物
    @Override
    public void registerStudent(RegisterVO registerVO) {
        //1.验证邀请码
        QueryWrapper<Classroom> query = new QueryWrapper<>();
        query.eq("invite_code",registerVO.getInviteCode());
        Classroom classroom = classroomMapper.selectOne(query);
        if(classroom==null){
            throw ServiceException.unprocesabelEntity("邀请码错误");
        }
        //2.手机号是否注册
        User user = userMapper.findUserByUsername(registerVO.getPhone());
        if(user!=null){
            throw ServiceException.unprocesabelEntity("手机号已被注册");
        }
        //3.注册
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        String password = encoder.encode(registerVO.getPassword());

        User user1 = new User();
        user1.setUsername(registerVO.getPhone());
        user1.setPassword("{bcrypt}"+password);
        user1.setNickname(registerVO.getNickname());
        user1.setClassroomId(classroom.getId());
        user1.setCreatetime(LocalDateTime.now());
        user1.setLocked(0);
        user1.setEnabled(1);

        //4.存储数据
        int num = userMapper.insert(user1);
        if(num!=1){
            throw ServiceException.busy();
        }
        //5.分配权限
        UserRole userRole = new UserRole();
        userRole.setUserId(user1.getId());
        userRole.setRoleId(2);
        int num2 = userRoleMapper.insert(userRole);
        if(num2!=1){
            throw ServiceException.busy();
        }
    }
    private Timer timer = new Timer();
    {
        timer.schedule(
                new TimerTask() {
                    @Override
                    public void run() {
                        synchronized (teachers){
                            teachers.clear();
                            teacherMap.clear();
                            log.debug("定期清理完成");
                        }
                    }
                }, 1000 * 60 * 30,1000 * 60 * 30);
    }
    @Override
    public List<User> getTeachers() {
        if(teachers.isEmpty()){
            synchronized (teachers){
                if(teachers.isEmpty()){
                    teachers.addAll(userMapper.selectTeachers());
                    for (User teacher : teachers){
                        teacherMap.put(teacher.getNickname(),teacher);
                    }
                }
            }
        }
        return teachers;
    }
    private List<User> teachers =  new CopyOnWriteArrayList<>();
    private Map<String,User> teacherMap = new ConcurrentHashMap<>();
    @Override
    public Map<String, User> getTeacherMap() {
        if (teacherMap.isEmpty()){
            getTeachers();
        }
        return teacherMap;
    }

    @Autowired
    private IUserCollectService userCollectService;
    @Autowired
    private IQuestionService questionService;
    @Autowired
    private IUserQuestionService userQuestionService;
    @Override
    public UserVO getCurrentUserVo(String username) {
        UserVO user = userMapper.findUserVOByUserName(username);
        int collectionCount  = userCollectService.countCollectsByUserId(user.getId());
        int questionCount  = questionService.countQuestionsByUserId(user.getId());
        int taskCount = userMapper.countTasks(user.getId());
        user.setQuestions(questionCount);
        user.setCollections(collectionCount);
        user.setTasks(taskCount);
        return user;
    }
    @Autowired
    private UserCollectMapper userCollectMapper;
    @Override
    public Integer getCollects(Integer id) {
        QueryWrapper<UserCollect> query = new QueryWrapper<>();
        query.eq("question_id",id);
        return userCollectMapper.selectCount(query);


    }

    @Override
    public Integer resetPassword(String userName,ReSetVO reSetVO) {
        User user = userMapper.findUserByUsername(userName);
        String myOldPass = user.getPassword();
        myOldPass = myOldPass.substring(8);
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        log.info("myOldPass:{}",myOldPass);
        log.info("OldPass:{}",reSetVO.getOldPass());
        log.info("1111:{}",encoder.matches(reSetVO.getOldPass(),myOldPass));
        if (encoder.matches(reSetVO.getOldPass(),myOldPass)){
            reSetVO.setNewPass("{bcrypt}"+encoder.encode(reSetVO.getNewPass()));
            int num = userMapper.resetPassword(reSetVO.getNewPass(),userName);
            if(num == 1){
                return num;
            }else {
                throw ServiceException.busy();
            }
        }else {
            throw ServiceException.unprocesabelEntity("11111");
        }


    }

    @Override
    public UserInfoVO getUserInfoVoByUserName(String username) {
       UserInfoVO userInfoVO = userMapper.selectUserInfoVOByUserName(username);
       return userInfoVO;
    }

    @Override
    public void UpdateUserInfo(String username, UserInfoVO userInfoVO) {
        User user = userMapper.findUserByUsername(username);
        user.setNickname(userInfoVO.getNickname())
                .setSex(userInfoVO.getSex())
                .setBirthday(userInfoVO.getBirthday())
                .setSelfIntroduction(userInfoVO.getSelfIntroduction());
        int num = userMapper.updateById(user);
        if(num!=1){
            throw ServiceException.busy();
        }
    }




    @Override
    public UserDetails getUserDetails(String username) {
        User user = userMapper.findUserByUsername(username);
        if(user==null){
            return null;
        }
        List<Permission> permissions = userMapper.findUserPermissionsById(user.getId());
        String[] auth = new String[permissions.size()];
        int i;
        for ( i = 0; i < auth.length; i++) {
            auth[i] = permissions.get(i).getName();
        }


        List<Role> roles = userMapper.findUserRolesById(user.getId());
        auth = Arrays.copyOf(auth,auth.length+roles.size());
        for (Role role : roles) {
            auth[i++] = role.getName();
        }


        UserDetails userDetails = org.springframework.security.core.userdetails.User
                                  .builder()
                                  .username(user.getUsername())
                                  .password(user.getPassword())
                                  .authorities(auth)
                                  .accountLocked(user.getLocked()==1)
                                  .disabled(user.getEnabled()==0)
                                  .build();
        return userDetails;

    }


}
